package jBittorrentAPI.strategy;

import jBittorrentAPI.DownloadManager;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.Random;

public class SegmentsAlgoritme implements PiecePickingStrategy {

	BitSet segments;
	DownloadManager dm;
	int numbersOfSegementToRunWith = 2;
	int segmentsize;
	PiecePickingStrategy pps;
	ArrayList<Integer> segmentsSet1 = new ArrayList<Integer>();
	ArrayList<Integer> segmentsSet2 = new ArrayList<Integer>();

	public SegmentsAlgoritme(DownloadManager dm, int nbPieces, int segmentsize) {
		int n = nbPieces % segmentsize;

		segments = new BitSet();

		if(n == 0){
			segments = new BitSet(nbPieces/segmentsize);

		}else{
			segments = new BitSet((nbPieces/(segmentsize-n))+1);
		}

		this.segmentsize = segmentsize;
		this.pps = new RarestFirstAlgoritme(dm);

		n = dm.isComplete.nextClearBit(0);

		if(n > 0 && n < dm.getNumberOfPieces()){
			int m = n % segmentsize;
			if(m == 0){
				segments.set(0, n/segmentsize);
			}else{
				segments.set(0, n/(segmentsize-m)+1);
			}
		}
		
		this.dm = dm;
	}

	@Override
	public int choosingAlgoritme(ArrayList<Integer> possible) {
		return chooseSegmentsAlgoritme();
	}

	@Override
	public synchronized void removeIndex(int i) {
		if(segmentsSet1.contains(i)){
			segmentsSet1.remove(new Integer(i));
		}else{
			segmentsSet2.remove(new Integer(i));
		}
	}

	private synchronized int chooseSegmentsAlgoritme(){
		if(segmentsSet1.size() == 0){
			if(segmentsSet2.size() > 0){
				segmentsSet1.addAll(segmentsSet2);
				segmentsSet2.clear();
			}else{
				int n = segments.nextClearBit(0);
				segments.set(n);
				int startPiece = (n == 0) ? 0: n*segmentsize;
				int endPiece = startPiece+segmentsize;
				for(int i = startPiece; i < endPiece; i++){
					if(i >= dm.getNumberOfPieces()) break;
					if(!dm.isComplete.get(i)){
						segmentsSet1.add(i);
					}
				} 
			}
		}

		if(segmentsSet2.size() == 0){
			int n = segments.nextClearBit(0);
			segments.set(n);
			int startPiece = (n == 0) ? 0: n*segmentsize;
			int endPiece = startPiece+segmentsize;
			for(int i = startPiece; i < endPiece; i++){
				if(i >= dm.getNumberOfPieces()) break;
				if(!dm.isComplete.get(i)){
					segmentsSet2.add(i);
				}
			} 
		}

		Random r = new Random(System.currentTimeMillis());
		int m = -1;
		if( r.nextInt(10) < 9){
			if(segmentsSet1.size() > 0){
				m = pps.choosingAlgoritme(segmentsSet1);
				dm.setRequested(m, true);
			}else if(segmentsSet2.size() > 0){
				m = pps.choosingAlgoritme(segmentsSet2);
				dm.setRequested(m, true);
			}
			return m;
		}else{
			if(segmentsSet2.size() > 0){
				m = pps.choosingAlgoritme(segmentsSet2);
				dm.setRequested(m, true);
			}else if(segmentsSet1.size() > 0){
				m = pps.choosingAlgoritme(segmentsSet1);
				dm.setRequested(m, true);
			}

			return m;
		}
	}
}